package cn.agiledata.bank.linkbank.impl.icbc;

import java.math.BigDecimal;
import java.util.Date;

import cn.agiledata.bank.common.util.DateUtil;
import cn.agiledata.bank.linkbank.exception.LinkBankException;
import cn.agiledata.bank.linkbank.impl.AbstractBankPayRequest;

/**
 * 中国工商银行网上银行b2b支付请求
 * 
 * @author maxianbo
 * 
 */
public final class IcbcB2bNetPayRequest extends IcbcNetPayRequest {

    protected void init() {
        setParameter(IcbcB2bNetConstant.INTERFACE_NAME, "B2B"); // 接口名称
        setParameter(IcbcB2bNetConstant.INTERFACE_VERSION, "001.001.001.001"); // 接口版本号
        setParameter(IcbcB2bNetConstant.CURRENCY_TYPE,
                IcbcB2bNetConstant.CURRENCY_TYPE_CNY); // 货币类型：人民币
        setParameter(IcbcB2bNetConstant.VERIFY_JOIN, "2"); // 检验联名：固定上传2
        setParameter(IcbcB2bNetConstant.RESULT_TYPE,
                IcbcB2bNetConstant.RESULT_TYPE_ONLY_SUCCESS); // 结果类型：仅成功时通知（不能为其它值）
        setParameter(IcbcB2bNetConstant.GOODS_ID, "0001"); // 商品编号
        setParameter(IcbcB2bNetConstant.GOODS_NAME, ""); // 商品名称
        setParameter(IcbcB2bNetConstant.GOODS_COUNT, "1"); // 商品数量
        setParameter(IcbcB2bNetConstant.REMARK2, ""); // 商户提示
    }

    protected final AbstractBankPayRequest getCopiedInstance() {
        IcbcNetPayRequest request = new IcbcB2bNetPayRequest();
        request.certFilePath = this.certFilePath;
        request.keyFilePath = this.keyFilePath;
        request.cryptoKeyValidator = this.cryptoKeyValidator;
        return request;
    }

    public void setMerchantId(String merchantId) {
        setParameter(IcbcB2bNetConstant.MERCHANT_ID, merchantId);
    }

    public void setMerchantAccount(String merchantAccount) {
        setParameter(IcbcB2bNetConstant.MERCHANT_ACCOUNT, merchantAccount);
        setParameter(IcbcB2bNetConstant.MERCHANT_COLLECT_ACCOUNT,
                merchantAccount);
    }

    public String getMerchantUrl() {
        return getParameter(IcbcB2bNetConstant.MERCHANT_URL);
    }

    public void setMerchantUrl(String merchantUrl) {
        merchantUrl = handleMerchantUrl(merchantUrl);
        setParameter(IcbcB2bNetConstant.MERCHANT_URL, merchantUrl);
    }

    public void setOrderId(String orderId) {
        setParameter(IcbcB2bNetConstant.ORDER_ID, orderId);
    }

    public void setAmount(BigDecimal amount) {
        BigDecimal hundred = new BigDecimal(100.0d);
        amount = amount.multiply(hundred).setScale(0);
        setParameter(IcbcB2bNetConstant.AMOUNT, amount.toString());
        setParameter(IcbcB2bNetConstant.CARRIAGE_AMOUNT, amount.toString());
    }

    public void setDate(Date date) {
        String dateValue = DateUtil.date2String(date,
                IcbcB2bNetConstant.DATE_FORMAT);
        setParameter(IcbcB2bNetConstant.DATE, dateValue);
    }

    public void setRemark(String remark) {
        setParameter(IcbcB2bNetConstant.REMARK, remark);
    }

    public void setDigitalSign(String digitalSign) {
        setParameter(IcbcB2bNetConstant.REQUEST_DIGITAL_SIGN, digitalSign);
    }

    public void setCertCode(String certCode) {
        setParameter(IcbcB2bNetConstant.CERT_CODE, certCode);
    }

    public String generateDigitalSign(String cryptoKey)
            throws LinkBankException {
        String certCode = IcbcNetPayUtils.getPublicKeyCode(this.certFilePath);
        setCertCode(certCode);
        String[] keys = { IcbcB2bNetConstant.INTERFACE_NAME,
                IcbcB2bNetConstant.INTERFACE_VERSION,
                IcbcB2bNetConstant.MERCHANT_ID,
                IcbcB2bNetConstant.MERCHANT_URL, IcbcB2bNetConstant.ORDER_ID,
                IcbcB2bNetConstant.AMOUNT, IcbcB2bNetConstant.CURRENCY_TYPE,
                IcbcB2bNetConstant.VERIFY_JOIN, IcbcB2bNetConstant.RESULT_TYPE,
                IcbcB2bNetConstant.DATE, IcbcB2bNetConstant.MERCHANT_ACCOUNT,
                IcbcB2bNetConstant.MERCHANT_COLLECT_ACCOUNT };
        String digitalSign = IcbcNetPayUtils.getDigitalSign(getParameters(),
                keys, cryptoKey, this.keyFilePath, true);
        setDigitalSign(digitalSign);
        return digitalSign;
    }

}
